package world.gameMenager;

import gui.gui2d.Promotion;
import gui.gui2d.highLevelPanels.utils.GuiTrigger;

import java.util.Observable;

import multiplayer.lan.Move;
import multiplayer.lan.utility.Message;
import utility.Color;
import utility.Point;
import world.ChessBoardMenager;
import world.Piece;
import world.PownPromotion;
import world.pieces.Pown;
import world.player.Player;

public class GameManagerVsPc extends GameManager{
	Castling castling = new Castling();

	boolean promotion=false;
	Point pointPromotion=new Point(0, 0);
	utility.Color colorPromotion;

	public  void move(final Player currentPlayer , final Point from, final Point to){
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				move2(currentPlayer , from,  to);

			}
		});		
		t.start();
	}
	

	private void move2(Player currentPlayer , Point from, Point to){
		ChessBoardMenager cbm = getChess().getChessBoardMenager();
		//mangio o muovo?
		if(cbm.getMatrix()[to.getX()][to.getY()]==null){//muovo
			
			
			if(cbm.canMovePiece(from, to)){
				cbm.move(from, to);
				
				setChanged();
				notifyObservers(new Move(currentPlayer, from, to));	
				
				setLastToPlay(currentPlayer);
				
				if(cbm.checkMate!=null){
					String colore= cbm.checkMate.equals(utility.Color.BLACK)? "Nero" : "Bianco"; 		
					setChanged();
					notifyObservers(new GuiTrigger(GuiTrigger.MATE,currentPlayer));
					return;
				}
				
				if(cbm.isBlackCheck()){
					setChanged();
					notifyObservers(new GuiTrigger(GuiTrigger.CHECK, cbm.getBlackKingPosition()));
				}else if(cbm.isWhiteCheck()){
					setChanged();
					notifyObservers(new GuiTrigger(GuiTrigger.CHECK, cbm.getWhiteKingPosition()));
				}
				
				
				castling(currentPlayer, from, to, cbm);
				pownPromotion(currentPlayer, from, to, cbm);

			}else{
				setChanged();
				notifyObservers(new GuiTrigger(GuiTrigger.NO_POSSIBLE_MOVE, null));
			}
		}else{//mangio
			if(cbm.canEatPiece(from, to)){
				
				
				
				
				setChanged();
				notifyObservers(new Move(currentPlayer, from, to));
				
				setLastToPlay(currentPlayer);
				
				
				setChanged();
				notifyObservers(new GuiTrigger(GuiTrigger.EAT_PIECE, cbm.getMatrix()[to.getX()][to.getY()]));
				
				cbm.eat(from, to);
				
				if(cbm.checkMate!=null){
					String colore= cbm.checkMate.equals(utility.Color.BLACK)? "Nero" : "Bianco"; 
					//System.out.println("Ha vinto il "+colore);
					setChanged();
					notifyObservers(new GuiTrigger(GuiTrigger.MATE,currentPlayer));
					return;
				}
				if(cbm.isBlackCheck()){
					setChanged();
					notifyObservers(new GuiTrigger(GuiTrigger.CHECK, cbm.getBlackKingPosition()));
				}else if(cbm.isWhiteCheck()){
					setChanged();
					notifyObservers(new GuiTrigger(GuiTrigger.CHECK, cbm.getWhiteKingPosition()));
				}
				

				pownPromotion(currentPlayer, from, to, cbm);


			}else{
				setChanged();
				notifyObservers(new GuiTrigger(GuiTrigger.NO_POSSIBLE_MOVE, null));
			}
		}
	}

	private void pownPromotion(Player currentPlayer, Point from, Point to,ChessBoardMenager cbm) {
		Piece[][] matrix= cbm.getMatrix();

		if(currentPlayer.getColor().equals(utility.Color.BLACK)){
			if(matrix[to.getX()][to.getY()] instanceof Pown){
				if(to.getX()==0){
					promotion=true;
					pointPromotion=to;
					colorPromotion=utility.Color.BLACK;

					setChanged();
					notifyObservers(new PownPromotion(currentPlayer,to));

					return;
				}
			}
		}else if(currentPlayer.getColor().equals(utility.Color.WHITE)){
			if(matrix[to.getX()][to.getY()] instanceof Pown){
				if(to.getX()==7){
					promotion=true;
					pointPromotion=to;
					colorPromotion=utility.Color.WHITE;
					setChanged();
					notifyObservers(new PownPromotion(currentPlayer,to));
					return;
				}
			}
		}
		promotion=false;
	}

	private void castling(Player currentPlayer, Point from, Point to,
			ChessBoardMenager cbm) {
		if(castling.isCastlingBlackRight(currentPlayer, from, to ,cbm.getMatrix())){
			cbm.move(new Point(0, 7), new Point(0,5));
			setChanged();
			notifyObservers(new Move(currentPlayer, new Point(0, 7), new Point(0,5)));
		}
		
		if(castling.isCastlingBlackLeft(currentPlayer, from, to ,cbm.getMatrix())){
			cbm.move(new Point(0, 0), new Point(0,3));
			setChanged();
			notifyObservers(new Move(currentPlayer, new Point(0, 0),  new Point(0,3)));
		}
		if(castling.isCastlingWhiteRight(currentPlayer, from, to ,cbm.getMatrix())){
			cbm.move(new Point(7, 7), new Point(7,5));
			setChanged();
			notifyObservers(new Move(currentPlayer,new Point(7, 7),new Point(7,5)));
		}
		if(castling.isCastlingWhiteLeft(currentPlayer, from, to ,cbm.getMatrix())){
			cbm.move(new Point(7, 0), new Point(7,3));
			setChanged();
			notifyObservers(new Move(currentPlayer, new Point(7, 0), new Point(7,3)));
		}
	}
	
	
	public void makePromotionPown( Piece p){
		if(promotion=true){
			p.setColor(Color.BLACK);
			Piece pi =(Piece) p.clone();
			pi.setColor(colorPromotion);
			setChanged();
			notifyObservers(new Promotion(pointPromotion, pi));
			getChess().getChessBoardMenager().replacePice(pointPromotion, pi);
			promotion=false;
			setChanged();
			notifyObservers(new GuiTrigger(GuiTrigger.LAST_TO_PLAY, lastToPlay));

		}
	}
	
	
	public void receivePromotionFromIA(Piece p){
		p.setColor(colorPromotion);
		getChess().getChessBoardMenager().replacePice(pointPromotion, p);
		setChanged();
		notifyObservers(new GraphicsUpdatePromotion(pointPromotion, p));
		setChanged();
		notifyObservers(new GuiTrigger(GuiTrigger.LAST_TO_PLAY, lastToPlay));

	}
	
	

	@Override
	public void update(Observable o, Object arg) {}

	@Override
	public boolean canMove(Player p) {
		return lastToPlay!=p;
	}

}
